//
// Created by EmFi on 2023/5/14.
//

#include "../define.h"

#ifndef DBMS_NODE_H
#define DBMS_NODE_H

#include <iostream>
#include "NodeType.h"

using namespace std;

template<class K>
class Node {
protected:
    // 节点的阶，即树的阶
    const int order;
    // 节点容量，内部结点中为键容量，叶子结点中为数据容量，值为阶的两倍
    const int capacity;
    // 指针容量，内部结点中为指向子树的指针个数，值为阶的两倍，叶子节点无意义
    const int pointerCapacity;

    // 结点类型
    NodeType type;

    // 键数组
    K *keys;
    // 有效长度，对中间结点指键个数，对叶子结点指数据个数
    int length;

    // 指向父结点的指针，标准B+树中并没有该指针，加上是为了更快地实现结点分裂和旋转等操作
    Node<K> *father;
public:
    Node(int order) : order(order), capacity(order * 2), pointerCapacity(order * 2 + 1) {
        // 初始化数据
        this->length = 0;
        this->father = nullptr;
        this->keys = new K[this->capacity];
        for (int i = 0; i < this->capacity; i++) {
            this->keys[i] = NULL;
        }
    }

    virtual ~Node() {
        delete this->keys;
    }

    // 获取该节点的上一个兄弟节点指针
    Node<K> *getPrevBrother() {
        auto *fa = this->father;
        // 如果该节点没有父节点，则也无兄弟节点
        if (fa == nullptr) {
            return nullptr;
        }

        // 从父节点中找到本节点的位置
        for (int i = 0; i <= fa->getLength(); i++) {
            if (fa->getPointer(i) == this) {
                if (i == 0) {
                    // 如果本节点在父节点中是第一个孩子，返回空指针
                    return nullptr;
                } else {
                    // 否则，则兄弟节点为父节点中本节点的前一个节点
                    return fa->getPointer(i - 1);
                }
            }
        }

        return nullptr;
    }

    // 获取该节点的下一个兄弟节点指针
    Node<K> *getNextBrother() {
        auto *fa = this->father;
        // 如果该节点没有父节点，则也无兄弟节点
        if (fa == nullptr) {
            return nullptr;
        }

        // 从父节点中找到本节点的位置
        for (int i = 0; i <= fa->getLength(); i++) {
            if (fa->getPointer(i) == this) {
                if (i == fa->getLength()) {
                    // 如果本节点在父节点中是最后一个孩子，返回空指针
                    return nullptr;
                } else {
                    // 否则，则兄弟节点为父节点中本节点的后一个节点
                    return fa->getPointer(i + 1);
                }
            }
        }

        return nullptr;
    }

    virtual Node<K> *getPointer(int index) {
        return nullptr;
    }

    Node<K> *getFather() const {
        return this->father;
    }

    void setFather(Node<K> *fa) {
        this->father = fa;
    }

    NodeType getType() const {
        return this->type;
    }

    void setType(NodeType t) {
        this->type = t;
    }

    int getLength() const {
        return this->length;
    }

    void setLength(int len) {
        this->length = len;
    }

    int getCapacity() const {
        return this->capacity;
    }

    int getPointerCapacity() const {
        return this->pointerCapacity;
    }

    K getKey(int index) const {
        return this->keys[index];
    }

    void setKey(int index, K key) {
        this->keys[index] = key;
    }

    K *getKeys() const {
        return this->keys;
    }
};

#endif //DBMS_NODE_H
